package com.osce.ex.service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.csce.domain.entity.exam.ExExercise;
import com.csce.domain.entity.exam.vo.ExExamQuestion;
import com.csce.domain.entity.exam.vo.ExStatus;
import com.doudou.core.container.ArrUtil;
import com.doudou.core.container.MapUtil;
import com.doudou.core.lang.ObjUtil;
import com.osce.common.constant.CacheConstants;
import com.osce.common.utils.DateUtils;
import com.osce.ex.mapper.ExExerciseMapper;
import com.osce.ex.service.tools.ExService;
import com.osce.interfaces.ex.IExExerciseService;
import com.osce.interfaces.ex.IExQuestionService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 理论练习Service业务层处理
 *
 * @author zzx
 * @since 2023-08-02
 */
@Service
public class ExExerciseServiceImpl extends ServiceImpl<ExExerciseMapper, ExExercise> implements IExExerciseService {

    @Resource
    private IExQuestionService questionService;
    @Resource
    private ExService exService;

    /**
     * 查询理论练习
     *
     * @param id 理论练习主键
     * @return 理论练习
     */
    @Override
    public ExExercise selectExExerciseById(Long id) {
        ExExercise exercise = baseMapper.selectExExerciseById(id);
        //如果已经完成练习，多返回一个题目做题详情
        if (exercise.getStatus().equals(3)) {
            Map<Long, ExExamQuestion> exExamQuestions = baseMapper.selectExerciseQuestions(id);
            return exercise.setExamQuestions(exExamQuestions).setQuestionIds(exExamQuestions.keySet());
        }
        //如果查询了单个理论练习，但是开始时间为空，则修改开始时间和状态
        if (ObjUtil.isEmpty(exercise.getStartTime())) {
            exercise.setStartTime(new Date());
            exercise.setStatus(2);
            updateExExercise(exercise);
        }
        return exercise.setQuestionIds(baseMapper.selectExQuestionIdsById(id));
    }

    /**
     * 查询理论练习列表
     *
     * @param exExercise 理论练习
     * @return 理论练习
     */
    @Override
    public List<ExExercise> selectExExerciseList(ExExercise exExercise) {
        return baseMapper.selectExExerciseList(exExercise);
    }

    /**
     * 新增理论练习
     *
     * @param exExercise 理论练习
     * @return 结果
     */
    @Override
    @Transactional
    public int insertExExercise(ExExercise exExercise, Long... questionIds) {
        exExercise.setCreateTime(DateUtils.getNowDate());
        int i = baseMapper.insertExExercise(exExercise);
        if (i > 0 && ArrUtil.isNotEmpty(questionIds)) {
            baseMapper.insertExExerciseQuestion(exExercise.getId(), questionIds);
        }
        return i;
    }

    @Override
    public int createExExercise(ExExercise exExercise) {
        Map<Integer, Integer> map = exService.analyseSig(exExercise.getSig(), exExercise.getCheckeds(), exExercise.getQuestionCount());
        if (CacheConstants.OPTIONAL.equals(exExercise.getSig())) {//自选
            exExercise.setQuestionCount(MapUtil.valueSumInt(map));
        }
        //随机获取题目编号
        List<Long> questionIds = questionService.randomIdsByTopic(map);
        return insertExExercise(exExercise, questionIds.toArray(new Long[0]));
    }

    /**
     * 修改理论练习
     *
     * @param exExercise 理论练习
     * @return 结果
     */
    @Override
    public int updateExExercise(ExExercise exExercise) {
        return baseMapper.updateExExercise(exExercise);
    }

    /**
     * 批量删除理论练习
     *
     * @param ids 需要删除的理论练习主键
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteExExerciseByIds(Long[] ids) {
        baseMapper.deleteExExerciseQuestionByIds(ids);
        return baseMapper.deleteExExerciseByIds(ids);
    }

    /**
     * 删除理论练习信息
     *
     * @param id 理论练习主键
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteExExerciseById(Long id) {
        baseMapper.deleteExExerciseQuestionByIds(id);
        return baseMapper.deleteExExerciseById(id);
    }

    /**
     * 交卷
     *
     * @param id      练习id
     * @param answers 答案集合
     */
    @Override
    @Transactional
    public int submit(Long id, Integer timer, Map<Long, Object> answers) {
        //查询练习详情
        ExStatus judge = exService.judge(id, baseMapper.selectExQuestionIdsById(id), answers);
        ExExercise exercise = ExExercise.builder().id(id).status(3).
                rightCount(judge.getSuccess()).
                score(judge.getScore()).answerTime(timer).
                endTime(new Date()).build();
        //修改每一题的答案
        updateExExerciseQuestion(judge.getExamQuestionList());
        return updateExExercise(exercise);
    }

    /**
     * 提交后修改答题
     *
     * @param examQuestionList
     */
    private void updateExExerciseQuestion(List<ExExamQuestion> examQuestionList) {
        for (ExExamQuestion exExamQuestion : examQuestionList) {
            baseMapper.updateExExerciseQuestion(exExamQuestion);
        }
    }
}
